import {
  CanActivate,
  ExecutionContext,
  Inject,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants, guardConstants } from './constants';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';

@Injectable()
export class AuthorizeGuard implements CanActivate {
  constructor(
    private readonly jwtService: JwtService,
    @Inject(CACHE_MANAGER) private cacheManager: Cache,
  ) {}
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    /**
     * 因为加了全局路由守卫
     * 这里添加白名单路由
     */
    if (guardConstants.routeWhiteList.includes(request.route.path)) {
      return true;
    }
    const token = request.headers.authorization;
    if (!token) {
      throw new UnauthorizedException();
    }
    // token 失效判断 类似黑明单 同一用户只能有一个token能使用
    const payload = this.jwtService.decode(token);
    console.info(payload);
    const cachedToken = await this.cacheManager.get(`TOKEN-${payload.sub}`);
    console.info(token);
    console.info(`TOKEN-${payload.sub}`, cachedToken);
    if (!cachedToken || cachedToken !== token) {
      throw new UnauthorizedException();
    }
    try {
      await this.jwtService.verifyAsync(token, {
        secret: jwtConstants.secret,
      });
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }
}
